package com.caiyi.financial.nirvana.sms.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import com.caiyi.financial.nirvana.sms.queue.SendQueueEntity;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 公共辅助类
 */
public class CommUtil {


    private static final Logger logger = LoggerFactory.getLogger(CommUtil.class);

    private CommUtil() {

    }

    private static final String YD = "^1(3[4-9]|47|5[012789]|78|8[23478]|98)\\d{8}$|^170[356]\\d{7}$|^10648\\d{8}$";
    private static final String LT = "^1(3[0-2]|45|5[56]|7[156]|8[56]|66)\\d{8}$|^170[4789]\\d{7}$|^10646\\d{8}$";
    private static final String DX = "^1([35]3|7[37]|8[019]|99)\\d{8}$|^170[012]\\d{7}$|^10649\\d{8}$";
    private static final Pattern YD_PATTERN = Pattern.compile(YD);
    private static final Pattern LT_PATTERN = Pattern.compile(LT);
    private static final Pattern DX_PATTERN = Pattern.compile(DX);
    public static long NODE_ID = 0;
    private static final AtomicLong BATCHIDSEED = new AtomicLong();
    private static final AtomicLong MESSAGEIDSEED = new AtomicLong();
    private static final int CONTENT_SPLIT_SIZE = 67;
    private static final int CONTENT_MAX_SIZE = 70;
    public final static Map<String, SendQueueEntity> M2B = new ConcurrentHashMap();

    public static final ThreadLocal<SimpleDateFormat> YYMMDDHHMMSS = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyMMddHHmmss");
        }
    };

    public static final ThreadLocal<SimpleDateFormat> YYYY_MM_DD_HH_MM_SS = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    /**
     * 借助FastJson Object转Map
     *
     * @param object obj
     * @return map
     */
    public static Map<String, Object> object2Map(Object object) {
        JSONObject jsonObject = (JSONObject) JSON.toJSON(object);
        Set<Map.Entry<String, Object>> entrySet = jsonObject.entrySet();
        Map<String, Object> map = new HashMap<>();
        for (Map.Entry<String, Object> entry : entrySet) {
            if (entry.getValue() != null && !entry.getValue().toString().equals(""))
                map.put(entry.getKey(), entry.getValue());
        }
        return map;
    }

    /**
     * 生产消息ID
     */
    public static final String generateMessageId() {
        long messageIdSeed = MESSAGEIDSEED.incrementAndGet();
        if (messageIdSeed >= 9000000) {
            messageIdSeed = messageIdSeed % 9000000;
        }
        messageIdSeed += 1000000;
        SimpleDateFormat df = YYMMDDHHMMSS.get();
        return df.format(new Date()) + NODE_ID + messageIdSeed;
    }

    /**
     * 生产批次id
     */
    public static final String generateBatchId() {
        long batchIdSeed = BATCHIDSEED.incrementAndGet();
        if (batchIdSeed >= 90000) {
            batchIdSeed = batchIdSeed % 90000;
        }
        batchIdSeed += 10000;
        SimpleDateFormat df = YYMMDDHHMMSS.get();
        return df.format(new Date()) + NODE_ID + batchIdSeed;
    }

    /**
     * 获取电话号码的运营商
     */
    public static int getPhoneOperator(String phone) {
        Matcher matcher = YD_PATTERN.matcher(phone);
        if (matcher.find()) {
            return 1;
        }
        matcher = LT_PATTERN.matcher(phone);
        if (matcher.find()) {
            return 2;
        }
        matcher = DX_PATTERN.matcher(phone);
        if (matcher.find()) {
            return 3;
        }
        return 0;
    }

    /***
     * 长短信内容拆分
     * @param messageContent
     * 单条短信最大长度默认70
     * 长短信每条长度默认67
     */
    public static List<String> splitLongContent(String messageContent) {
        return splitLongContent(messageContent, 0);
    }

    /***
     * 长短信内容拆分，带签名长度
     * @param messageContent
     * @param signLength
     * 单条短信最大长度默认70
     * 长短信每条长度默认67
     */
    public static List<String> splitLongContent(String messageContent, int signLength) {
        if (signLength < 0) {
            signLength = 0;
        }
        List<String> strLst = new ArrayList();
        StringBuffer strBuf = new StringBuffer(messageContent);
        if (strBuf.length() + signLength > CONTENT_MAX_SIZE) {
            int firstLength = CONTENT_SPLIT_SIZE - signLength;
            String first = strBuf.substring(0, firstLength);
            strBuf.delete(0, firstLength);
            strLst.add(first);
            while (strBuf.length() > CONTENT_SPLIT_SIZE) {
                String str = strBuf.substring(0, CONTENT_SPLIT_SIZE);
                strBuf.delete(0, CONTENT_SPLIT_SIZE);
                strLst.add(str);
            }
        }
        if (strBuf.length() > 0) {
            strLst.add(strBuf.toString());
        }

        return strLst;
    }

    public static boolean checkStatus(String lockKey, int second) {
        try {
            Long lock = JedisService.setnx(lockKey, "lock");
            // 设置有限期
            JedisService.expire(lockKey, second);
            if (lock != null && lock.intValue() == 1) {
                logger.info("lockKey is {}", lockKey);
                return true;
            } else {
                logger.info("lockKey is exit {}", lockKey);
                return false;
            }
        } catch (Exception e) {
            logger.error("CommUtil checkStatus lockKey exception {}", e);
            return true;
        }
    }

    /**
     * 导入文件
     *
     * @param stream
     * @return
     * @throws Exception
     */
    public static Set<String> readLines(InputStream stream) throws Exception {
        String fileName = "temp/" + System.currentTimeMillis() + ".csv";
        Set<String> phones = new HashSet<>();
        File tempFile = new File(fileName);
        FileUtils.copyInputStreamToFile(stream, tempFile);
        List<String> list = FileUtils.readLines(tempFile, "utf-8");
        for (String phone : list) {
            if (StringUtils.isNotBlank(phone)) {
                phones.add(phone.trim().replace(",", ""));
            }
        }
        FileUtils.deleteQuietly(tempFile);
        return phones;
    }


    /**
     * 获取客户端真实ip
     *
     * @param req request
     * @return ip
     */
    public static String getClientIp(HttpServletRequest req) {
        String ip = req.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = req.getHeader("x-real-ip");
        } else if (ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = req.getRemoteAddr();
        }
        logger.info("admin getClientIp ip : {}", ip);
        return ip;
    }

    /**
     * 获取调用环境
     *
     * @param env
     * @return
     */
    public static String getSendUrl(String env) {
        String sendUrl;
        if (Constant.ENV_PRO.equalsIgnoreCase(env)) {
            sendUrl = Constant.PRO_SEND_URL;
        } else {
            sendUrl = Constant.DEV_SEND_URL;
        }
        return sendUrl;
    }

    /**
     * 是否为验证码
     *
     * @param content
     * @return
     */
    public static boolean needFree(String content) {
        String[] codeFree = Constant.CODE_FREE.split(",");
        for (int i = 0; i < codeFree.length; i++) {
            if (content.contains(codeFree[i])) {
                return false;
            }
        }
        return true;
    }


}
